package com.ruoyi.system.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.enums.VideoParseResponse;
import com.ruoyi.common.utils.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * B站视频解析服务
 * @Author: JH-Ahua
 * @CreateTime: 2025/1/15
 */
@Service
public class BilibiliService {
    
    private static final Logger logger = LoggerFactory.getLogger(BilibiliService.class);
    
    // B站Cookie，用于获取高清视频
    private static final String COOKIE = "_uuid=;";
    
    /**
     * 解析B站视频
     * @param url B站分享链接
     * @return 解析结果
     */
    public VideoParseResponse parseBilibiliVideo(String url) {
        try {
            // 验证URL
            if (url == null || url.trim().isEmpty()) {
                return new VideoParseResponse(201, "链接不能为空！", null);
            }
            
            // 清理URL参数
            String cleanUrl = cleanUrlParameters(url);
            
            // 解析URL
            URL parsedUrl = new URL(cleanUrl);
            String host = parsedUrl.getHost();
            String path = parsedUrl.getPath();
            
            String bvid = "";
            
            // 处理不同的域名
            if ("b23.tv".equals(host)) {
                // 处理短链接重定向
                String redirectUrl = getRedirectUrl(cleanUrl);
                if (redirectUrl != null) {
                    URL redirectParsedUrl = new URL(redirectUrl);
                    bvid = redirectParsedUrl.getPath();
                } else {
                    return new VideoParseResponse(-1, "无法获取重定向链接", null);
                }
            } else if ("www.bilibili.com".equals(host) || "m.bilibili.com".equals(host)) {
                bvid = path;
            } else {
                return new VideoParseResponse(-1, "视频链接好像不太对！", null);
            }
            
            // 验证是否为视频链接
            if (!bvid.contains("/video/")) {
                return new VideoParseResponse(-1, "好像不是视频链接", null);
            }
            
            // 提取BVID
            bvid = bvid.replace("/video/", "");
            
            // 获取视频信息
            return getVideoInfo(bvid);
            
        } catch (Exception e) {
            logger.error("解析B站视频失败", e);
            return new VideoParseResponse(500, "解析失败: " + e.getMessage(), null);
        }
    }
    
    /**
     * 获取重定向URL
     * @param url 短链接
     * @return 重定向后的URL
     */
    private String getRedirectUrl(String url) {
        try {
            Map<String, String> headers = new HashMap<>();
            headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36");
            
            // 发送HEAD请求获取重定向URL
            return HttpUtils.getFinalUrl(url, headers);
        } catch (Exception e) {
            logger.error("获取重定向URL失败", e);
            return null;
        }
    }
    
    /**
     * 清理URL参数
     * @param url 原始URL
     * @return 清理后的URL
     */
    private String cleanUrlParameters(String url) {
        try {
            URL parsedUrl = new URL(url);
            String scheme = parsedUrl.getProtocol() + "://";
            String host = parsedUrl.getHost();
            String port = parsedUrl.getPort() != -1 ? ":" + parsedUrl.getPort() : "";
            String path = parsedUrl.getPath() != null ? URLDecoder.decode(parsedUrl.getPath(), StandardCharsets.UTF_8.toString()) : "";
            String fragment = parsedUrl.getRef() != null ? "#" + URLDecoder.decode(parsedUrl.getRef(), StandardCharsets.UTF_8.toString()) : "";
            
            // 移除认证信息
            host = host.replaceAll("^.*@", "");
            
            // 去掉路径末尾的斜杠
            path = path.replaceAll("/$", "");
            
            return scheme + host + port + path + fragment;
        } catch (Exception e) {
            logger.error("清理URL参数失败", e);
            return url;
        }
    }
    
    /**
     * 获取视频信息
     * @param bvid 视频ID
     * @return 视频信息
     */
    private VideoParseResponse getVideoInfo(String bvid) {
        try {
            // 构造请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json;charset=UTF-8");
            headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36");
            headers.put("Cookie", COOKIE);
            
            // 获取视频基本信息
            String apiUrl = "https://api.bilibili.com/x/web-interface/view?bvid=" + bvid;
            String response = HttpUtils.get(apiUrl, headers);
            
            if (response == null || response.isEmpty()) {
                return new VideoParseResponse(0, "解析失败！", null);
            }
            
            JSONObject jsonResponse = JSONObject.parseObject(response);
            
            if (!"0".equals(jsonResponse.getString("code"))) {
                return new VideoParseResponse(0, "解析失败！", null);
            }
            
            JSONObject data = jsonResponse.getJSONObject("data");
            String title = data.getString("title");
            String cover = data.getString("pic");
            String desc = data.getString("desc");
            JSONObject owner = data.getJSONObject("owner");
            JSONArray pages = data.getJSONArray("pages");
            
            List<VideoParseResponse.Video> videos = new ArrayList<>();
            String realVideoUrl = null;
            
            // 处理多P视频
            if (pages != null && !pages.isEmpty()) {
                for (int i = 0; i < pages.size(); i++) {
                    JSONObject page = pages.getJSONObject(i);
                    String cid = page.getString("cid");
                    String partTitle = page.getString("part");
                    Integer duration = page.getInteger("duration");
                    
                    // 获取视频直链
                    String videoApiUrl = "https://api.bilibili.com/x/player/playurl?otype=json&fnver=0&fnval=3&player=3&qn=112&bvid=" + bvid + "&cid=" + cid + "&platform=html5&high_quality=1";
                    String videoResponse = HttpUtils.get(videoApiUrl, headers);
                    
                    VideoParseResponse.Video video = new VideoParseResponse.Video();
                    video.setTitle(partTitle);
                    video.setDuration(duration);
                    video.setDurationFormat(formatDuration(duration));
                    video.setIndex(i + 1);
                    
                    if (videoResponse != null && !videoResponse.isEmpty()) {
                        JSONObject videoJson = JSONObject.parseObject(videoResponse);
                        JSONObject videoData = videoJson.getJSONObject("data");
                        
                        if (videoData != null && videoData.containsKey("durl")) {
                            JSONArray durl = videoData.getJSONArray("durl");
                            if (durl != null && !durl.isEmpty()) {
                                String videoUrl = durl.getJSONObject(0).getString("url");
                                // 提取真实视频地址（去除镜像前缀）
                                realVideoUrl = extractRealVideoUrl(videoUrl);
                                video.setUrl(realVideoUrl);
                            }
                        }
                    }
                    
                    if (video.getUrl() == null) {
                        video.setError("无法获取视频链接");
                    }
                    
                    videos.add(video);
                }
            }
            
            // 构建响应数据
            VideoParseResponse.VideoData responseData = new VideoParseResponse.VideoData();
            responseData.setTitle(title);
            responseData.setCover(cover);
            responseData.setDescription(desc);
            responseData.setUrl(realVideoUrl);
            
            // 用户信息 - 调整为统一结构
            responseData.setAuthor(owner.getString("name"));
            responseData.setUid(owner.getString("mid"));
            responseData.setAvatar(owner.getString("face"));
            
            // 设置默认值
            responseData.setLike(0L);
            responseData.setTime(System.currentTimeMillis());
            responseData.setImages("B站视频解析");
            responseData.setMusic("B站视频原声");
            
            // 多P视频信息
            if (videos.size() > 1) {
                responseData.setVideos(videos);
                responseData.setTotalVideos(videos.size());
            }
            
            return new VideoParseResponse(200, "解析成功！", responseData);
            
        } catch (Exception e) {
            logger.error("获取视频信息失败", e);
            return new VideoParseResponse(0, "解析失败！", null);
        }
    }
    
    /**
     * 提取真实视频地址
     * @param videoUrl 原始视频地址
     * @return 真实视频地址
     */
    private String extractRealVideoUrl(String videoUrl) {
        if (videoUrl == null) {
            return null;
        }
        // 替换镜像前缀
        return videoUrl.replaceAll(".*\\.bilivideo\\.com/", "https://upos-sz-mirrorhw.bilivideo.com/");
    }
    
    /**
     * 格式化时长
     * @param seconds 秒数
     * @return 格式化后的时长
     */
    private String formatDuration(Integer seconds) {
        if (seconds == null) {
            return "00:00:00";
        }
        
        int hours = seconds / 3600;
        int minutes = (seconds % 3600) / 60;
        int secs = seconds % 60;
        
        return String.format("%02d:%02d:%02d", hours, minutes, secs);
    }
}
